﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data.SqlClient;
using System.Data;
using System.Collections.ObjectModel;
using OverStore.Configuration.Builder.Fluent;
using OverStore.Configuration;
using OverStore.Runtime.Storage;
using OverStore.Configuration.Components;
using OverStore.Configuration.Storage;
using OverStore.Configuration.Builder;
using OverStore.Sql.TableSchema;
using System;
using System.Reflection;
using OverStore.Configuration.ObjectRepository.Depot;
using OverStore.Configuration.ObjectRepository.CommandSet;

namespace OverStore.TutorialAsTest.UnitTest.Configuration.Rdbms.AttachedKeys
{
    [TestClass]
    public class UpdateKey_SqlServer
    {
        protected OverStoreConfiguration CreateConfig()
        {
            return OverStoreFluent.Configure()
                .LogToConsole()
                .ConnectToDatabase<SqlConnection>(@"Data Source=.\sqlexpress;Initial Catalog=SqlServerTest;Integrated Security=True;MultipleActiveResultSets=True", ProcessOpenedReadersMode.ForciblyCloseReaders)
                .CustomClassRepository<Sample, int>()
                    .WithDepot(new DelegateDepotConfiguration<Sample, int>()
                                {
                                    IdentifierGenerator = Component.IdentifierGenerator.Delegate<Sample, int>((item, last) => item.Id),
                                    CreateInstanceFunction = () => new Sample(),
                                    StoreIdentifierCopy = (item, id) =>
                                    {
                                        item.Id = id;
                                    }
                                })
                    .WithMapper(Component.Mapper.Delegate<Sample>((item, name, p) =>
                        {
                            if (name == "Id")
                                return p.GetIdentifier<Sample, int>(item);
                            if (name == "Name")
                                return item.Name;
                            return Missing.Value;
                        },
                    (data, item, provider) =>
                    {
                        item.Name = data.GetString("Name");
                        if (data.ContainsName("Id"))
                            provider.PutNewIdentifier(item, Convert.ToInt32(data.GetInt32("Id")));
                    }))
                    .WithCommands(new TableCommandSetConfiguration()
                                {
                                    TableSchema = new Table
                                    {
                                        Name = "Sample",
                                        Columns = new ColumnBase[] 
                                                    { 
                                                        new Key<int> { Name = "Id" },
                                                        new Column<string> { Name = "Name" } 
                                                    }
                                    },
                                    CustomInsert =
                                     new AdoNetCommandConfiguration()
                                     {
                                         CommandType = CommandType.StoredProcedure,
                                         Sql = "InsertSample",
                                         ResultType = AdoCommandResultType.OutputParameters,
                                         Parameters = new Collection<AdoNetParameter>()
                                                         { 
                                                             new AdoNetParameter("Name", false, DbType.String),
                                                             new AdoNetParameter("Id", false, DbType.Int32)
                                                             {
                                                                 Direction = ParameterDirection.InputOutput
                                                             }
                                                         }
                                     }
                                })
                    .WithChangesTracker(Component.InstanceChangesTracker.Checksum<Sample, int>("Id", "Name"))
                    .NoErrorTransforming().ByIdentifierAttaching(i => i.Id)
                .EndObjectRepository()
            .End();
        }
    }
}
